// ml278
// Copyright (C) 2008 Bjørn Øivind Bjørnsen, Aleksander Gjermundsen, Knut Andre Tidemann, Thomas Hansen
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

#include <iostream>
#include <ostream>
#include <fstream>

using namespace std;

typedef unsigned char byte;

#pragma pack(push, 1)
struct TGA_HEADER
{
    byte  identsize;          // size of ID field that follows 18 byte header (0 usually)
    byte  colourmaptype;      // type of colour map 0=none, 1=has palette
    byte  imagetype;          // type of image 0=none,1=indexed,2=rgb,3=grey,+8=rle packed

    short colourmapstart;     // first colour map entry in palette
    short colourmaplength;    // number of colours in palette
    byte  colourmapbits;      // number of bits per palette entry 15,16,24,32

    short xstart;             // image x origin
    short ystart;             // image y origin
    short width;              // image width in pixels
    short height;             // image height in pixels
    byte  bits;               // image bits per pixel 8,16,24,32
    byte  descriptor;         // image descriptor bits (vh flip bits)
};
#pragma pack(pop)

int main()
{
	TGA_HEADER tg;
	ofstream fstream;

	fstream.open("lut.tga", ios::out | ios::binary); // use binary streams!

	tg.identsize = 0x0;
	tg.colourmaptype = 0x0;
	tg.imagetype = 0x2;

	tg.colourmapstart = 0x0;
	tg.colourmaplength = 0x0;
	tg.colourmapbits = 0x0;

	tg.xstart = 0x0;
	tg.ystart = 0x0;
	tg.width = 256;
	tg.height = 256;
	tg.bits = 0x18;
	tg.descriptor = 0x0;

	fstream.write((char*)&tg, sizeof(TGA_HEADER));
	
	// default to pink
	unsigned char lut[256][256][3];
	
	for(int i = 0; i < 256; i++) {
		for(int j = 0; j < 256; j++) {
			lut[i][j][0] = 0xff; // r
			lut[i][j][1] = 0x00; // g
			lut[i][j][2] = 0xff; // b
		}
	}
	
	// 0,3 - Sand 1
	// slope (0-100%)
	for(int i = 0; i < 26; i++) {
		// altitude (0-100%)
		for(int j = 0; j < 13; j++) {
			unsigned char g = 0x00; // x-index in pack
			unsigned char b = 0x03; // y-index in pack
			unsigned char r = 0x0c; // total index in pack
			
			lut[i][j][0] = r;
			lut[i][j][1] = g;
			lut[i][j][2] = b;
		}
	}
	
	// 1,3 - Sand 2
	// slope (0-100%)
	for(int i = 26; i < 40; i++) {
		// altitude (0-100%)
		for(int j = 0; j < 13; j++) {
			unsigned char g = 0x01; // x-index in pack
			unsigned char b = 0x03; // y-index in pack
			unsigned char r = 0x0d; // total index in pack
			
			lut[i][j][0] = r;
			lut[i][j][1] = g;
			lut[i][j][2] = b;
		}
	}

	// 1,0 - Grass
	// slope (0-100%)
	for(int i = 40; i < 64; i++) {
		// altitude (0-100%)
		for(int j = 0; j < 13; j++) {
			unsigned char g = 0x00; // x-index in pack
			unsigned char b = 0x01; // y-index in pack
			unsigned char r = 0x01; // total index in pack
			
			lut[i][j][0] = r;
			lut[i][j][1] = g;
			lut[i][j][2] = b;
		}
	}

	// 1,0 - Grass
	// slope (0-100%)
	for(int i = 64; i < 90; i++) {
		// altitude (0-100%)
		for(int j = 0; j < 13; j++) {
			unsigned char g = 0x00; // x-index in pack
			unsigned char b = 0x00; // y-index in pack
			unsigned char r = 0x00; // total index in pack
			
			lut[i][j][0] = r;
			lut[i][j][1] = g;
			lut[i][j][2] = b;
		}
	}

	// 1,0 - Grass
	// slope (0-100%)
	for(int i = 0; i < 40; i++) {
		// altitude (0-100%)
		for(int j = 13; j < 50; j++) {
			unsigned char g = 0x02; // x-index in pack
			unsigned char b = 0x00; // y-index in pack
			unsigned char r = 0x02; // total index in pack
			
			lut[i][j][0] = r;
			lut[i][j][1] = g;
			lut[i][j][2] = b;
		}
	}

	// 1,0 - Grass
	// slope (0-100%)
	for(int i = 40; i < 90; i++) {
		// altitude (0-100%)
		for(int j = 13; j < 51; j++) {
			unsigned char g = 0x00; // x-index in pack
			unsigned char b = 0x00; // y-index in pack
			unsigned char r = 0x00; // total index in pack
			
			lut[i][j][0] = r;
			lut[i][j][1] = g;
			lut[i][j][2] = b;
		}
	}

	// slope (0-100%)
	for(int i = 90; i < 128; i++) {
		// altitude (0-100%)
		for(int j = 0; j < 51; j++) {
			unsigned char g = 0x01; // x-index in pack
			unsigned char b = 0x00; // y-index in pack
			unsigned char r = 0x01; // total index in pack
			
			lut[i][j][0] = r;
			lut[i][j][1] = g;
			lut[i][j][2] = b;
		}
	}
	
	// slope (0-100%)
	for(int i = 128; i < 192; i++) {
		// altitude (0-100%)
		for(int j = 0; j < 51; j++) {
			unsigned char g = 0x01; // x-index in pack
			unsigned char b = 0x01; // y-index in pack
			unsigned char r = 0x05; // total index in pack
			
			lut[i][j][0] = r;
			lut[i][j][1] = g;
			lut[i][j][2] = b;
		}
	}

	// slope (0-100%)
	for(int i = 0; i < 51; i++) {
		// altitude (0-100%)
		for(int j = 51; j < 166; j++) {
			unsigned char g = 0x00; // x-index in pack
			unsigned char b = 0x02; // y-index in pack
			unsigned char r = 0x08; // total index in pack
			
			lut[i][j][0] = r;
			lut[i][j][1] = g;
			lut[i][j][2] = b;
		}
	}

	// slope (0-100%)
	for(int i = 51; i < 102; i++) {
		// altitude (0-100%)
		for(int j = 51; j < 166; j++) {
			unsigned char g = 0x01; // x-index in pack
			unsigned char b = 0x02; // y-index in pack
			unsigned char r = 0x09; // total index in pack
			
			lut[i][j][0] = r;
			lut[i][j][1] = g;
			lut[i][j][2] = b;
		}
	}

	// slope (0-100%)
	for(int i = 102; i < 192; i++) {
		// altitude (0-100%)
		for(int j = 51; j < 166; j++) {
			unsigned char g = 0x01; // x-index in pack
			unsigned char b = 0x01; // y-index in pack
			unsigned char r = 0x05; // total index in pack
			
			lut[i][j][0] = r;
			lut[i][j][1] = g;
			lut[i][j][2] = b;
		}
	}
	
	// slope (0-100%)
	for(int i = 192; i < 256; i++) {
		// altitude (0-100%)
		for(int j = 0; j < 166; j++) {
			unsigned char g = 0x03; // x-index in pack
			unsigned char b = 0x02; // y-index in pack
			unsigned char r = 0x0b; // total index in pack
			
			lut[i][j][0] = r;
			lut[i][j][1] = g;
			lut[i][j][2] = b;
		}
	}

	// slope (0-100%)
	for(int i = 0; i < 51; i++) {
		// altitude (0-100%)
		for(int j = 166; j < 256; j++) {
			unsigned char g = 0x03; // x-index in pack
			unsigned char b = 0x02; // y-index in pack
			unsigned char r = 0x0b; // total index in pack
			
			lut[i][j][0] = r;
			lut[i][j][1] = g;
			lut[i][j][2] = b;
		}
	}

	// slope (0-100%)
	for(int i = 0; i < 51; i++) {
		// altitude (0-100%)
		for(int j = 166; j < 256; j++) {
			unsigned char g = 0x03; // x-index in pack
			unsigned char b = 0x02; // y-index in pack
			unsigned char r = 0x0b; // total index in pack
			
			lut[i][j][0] = r;
			lut[i][j][1] = g;
			lut[i][j][2] = b;
		}
	}
	
	// slope (0-100%)
	for(int i = 51; i < 192; i++) {
		// altitude (0-100%)
		for(int j = 166; j < 256; j++) {
			unsigned char g = 0x03; // x-index in pack
			unsigned char b = 0x02; // y-index in pack
			unsigned char r = 0x0b; // total index in pack
			
			lut[i][j][0] = r;
			lut[i][j][1] = g;
			lut[i][j][2] = b;
		}
	}

	// slope (0-100%)
	for(int i = 192; i < 256; i++) {
		// altitude (0-100%)
		for(int j = 166; j < 256; j++) {
			unsigned char g = 0x03; // x-index in pack
			unsigned char b = 0x02; // y-index in pack
			unsigned char r = 0x0b; // total index in pack
			
			lut[i][j][0] = r;
			lut[i][j][1] = g;
			lut[i][j][2] = b;
		}
	}
	// last spot reserved for pink
	// --------------------------------
	
	// write contents to file
	for(int i = 0; i < 256; i++) {
		for(int j = 0; j < 256; j++) {
			// write
			// FORMAT: b, g, r
			fstream << lut[i][j][2]; // b
			fstream << lut[i][j][1]; // g
			fstream << lut[i][j][0]; // r
		}
	}
	
	fstream.close();

	return(0);
}
